package com.mhs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mhs.entity.Comment;
import com.mhs.mapper.CommentMapper;
import com.mhs.service.ICommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mhs.vo.ArticleVo;
import com.mhs.vo.CommentVo;
import com.mhs.vo.Result;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Fantasy0521
 * @since 2023-04-12
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {

    @Resource
    private CommentMapper commentMapper;

    /**
     * 根据文章id分页获取所有评论和所有子评论(使用递归)
     *
     * @param articleId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public Result getCommentsAndReply(Long articleId, Integer page, Integer pageSize) {
        //因为递归方法中要多次进行查询
        //此时分页要在执行完所有查询得到结果后再分页,需要使用分页插件PageHelper
        //todo 加入PageHelper启动不了,暂时不进行分页
        
        //1 从根节点-1开始,查询所有子节点
        List<CommentVo> comments = getCommentsByParentCommentId(articleId, -1L);
        
        //2 此时查出来的是一层一层的,需要处理后再交给前端
        //把所有子评论以及子评论的子评论统一放入ReplyComments 页面只做了两层显示 1父1子 即把孙子也当为子
        //记录所有评论数
        int totalChild = 0;
        for (CommentVo comment : comments) {
            List<CommentVo> tmpComments = new ArrayList<>();
            getReplyComments(tmpComments, comment.getReplyComments());
            totalChild += tmpComments.size();
            comment.setReplyComments(tmpComments);
        }
        
        return Result.success(comments);
    }


    /**
     * 从某个节点出发,依次查询该节点下还有哪些子节点,此处使用递归
     *
     * @param articleId
     * @param parentCommentId
     * @return
     */
    public List<CommentVo> getCommentsByParentCommentId(Long articleId, Long parentCommentId) {
        //1 以parentCommentId作为条件,查询此节点下的子节点
        //todo 将user信息也查出来
        List<CommentVo> comments = commentMapper.selectCommentsByParentCommentId(articleId,parentCommentId);
        //2 对子节点依次遍历查询出其子节点
        for (CommentVo comment : comments) {
            //3 此时把patentCommentId设为自己的Id,对其子节点在进行查询,实现递归
            List<CommentVo> replyComments = getCommentsByParentCommentId(articleId, comment.getId());
            //5 当开始设置子节点的时候已经遍历到叶子结点了,本轮递归结束
            comment.setReplyComments(replyComments);
        }
        //4 当没有字节点时即当前节点为叶子结点,开始回归
        return comments;
    }


    /**
     * 将所有子评论递归取出到一个List中,此处也需要用到递归
     * 也就是把其他子评论全部并排显示,不管他们是否还有父子关系
     *
     * @param comments
     * @return
     */
    private void getReplyComments(List<CommentVo> tmpComments, List<CommentVo> comments) {
        for (CommentVo c : comments) {
            tmpComments.add(c);
            getReplyComments(tmpComments, c.getReplyComments());
        }
    }


    /**
     * 添加评论
     * @param comment
     * @return
     */
    @Override
    public Result addComment(Comment comment) {
        //如果没有传父节点或者为0,则默认为根节点
        if (comment.getParentCommentId() == null || comment.getParentCommentId() == 0) {
            comment.setParentCommentId(-1L);
        }
        comment.setCreateTime(LocalDateTime.now());
        commentMapper.insert(comment);
        return Result.success("评论成功");
    }
}
